package org.groupg.project.configmanager.service;


import org.groupg.project.configmanager.model.SshConfig;

import java.io.IOException;


import java.io.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Consumer;

public class SshConnectionService {

    /**
     * 执行SSH连接
     */
    public static void connectToSsh(SshConfig config) throws IOException {
        String os = System.getProperty("os.name").toLowerCase();
        ProcessBuilder processBuilder = new ProcessBuilder();

        if (os.contains("win")) {
            // Windows系统 - 使用cmd.exe
            processBuilder.command("cmd.exe", "/c", "start", "cmd.exe", "/k", config.generateSshCommand());
        } else if (os.contains("mac")) {
            // Mac系统
            processBuilder.command("osascript", "-e",
                    String.format("tell application \"Terminal\" to do script \"%s\"", config.generateSshCommand()));
        } else {
            // Linux系统
            processBuilder.command("gnome-terminal", "--", "bash", "-c", config.generateSshCommand() + "; exec bash");
        }

        processBuilder.start();
    }

    /**
     * 测试SSH连接（使用ping）
     */
    public static boolean testSshConnection(SshConfig config) {
        try (ExecutorService es0 = Executors.newSingleThreadExecutor();
             ExecutorService es1 = Executors.newSingleThreadExecutor();) {
            String os = System.getProperty("os.name").toLowerCase();
            ProcessBuilder processBuilder = new ProcessBuilder();

            if (os.contains("win")) {
                processBuilder.command("cmd.exe", "/c", "ping", "-n", "1", config.getHost());
            } else {
                processBuilder.command("sh", "-c", String.format("ping -c 1 %s", config.getHost()));
            }

            Process process = processBuilder.start();

            // 使用StreamGobbler消费输出流，防止进程阻塞:cite[1]:cite[3]
            StreamGobbler outputGobbler = new StreamGobbler(process.getInputStream(), System.out::println);
            StreamGobbler errorGobbler = new StreamGobbler(process.getErrorStream(), System.err::println);


            es0.submit(outputGobbler);
            es1.submit(errorGobbler);

            int exitCode = process.waitFor();
            return exitCode == 0;

        } catch (IOException | InterruptedException e) {
            return false;
        }
    }

    /**
     * 执行命令并获取输出（用于需要读取结果的场景）
     */
    public static String executeCommandAndGetOutput(String[] command) throws IOException, InterruptedException {
        ProcessBuilder processBuilder = new ProcessBuilder(command);
        Process process = processBuilder.start();

        // 读取命令输出
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        StringBuilder output = new StringBuilder();
        String line;

        while ((line = reader.readLine()) != null) {
            output.append(line).append("\n");
        }

        // 等待进程完成并返回退出码
        int exitCode = process.waitFor();
        if (exitCode != 0) {
            throw new IOException("Command execution failed with exit code: " + exitCode);
        }

        return output.toString();
    }

    /**
     * StreamGobbler 用于消费进程的输出流，防止阻塞:cite[3]:cite[4]
     */
    private static class StreamGobbler implements Runnable {
        private InputStream inputStream;
        private Consumer<String> consumer;

        public StreamGobbler(InputStream inputStream, Consumer<String> consumer) {
            this.inputStream = inputStream;
            this.consumer = consumer;
        }

        @Override
        public void run() {
            new BufferedReader(new InputStreamReader(inputStream)).lines()
                    .forEach(consumer);
        }
    }
}